package com.gitee.melin.bee.core.jdbc;

import com.gitee.melin.bee.core.jdbc.relational.ConnectionInfo;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.SQLException;
import java.util.Map;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DriverConnectionFactory implements ConnectionFactory {
    private static final Logger LOG = LoggerFactory.getLogger(DriverConnectionFactory.class);

    private final Driver driver;

    private final String jdbcUrl;

    private final HikariDataSource dataSource;

    public DriverConnectionFactory(
            Driver driver,
            String jdbcUrl,
            ConnectionInfo connectionInfo,
            Map<String, String> properties,
            DataSource nativeDataSource) {

        this.driver = driver;
        this.jdbcUrl = jdbcUrl;

        HikariConfig config = new HikariConfig();
        config.setJdbcUrl(jdbcUrl);
        config.setUsername(connectionInfo.getUsername());
        config.setPassword(connectionInfo.getPassword());
        config.setMinimumIdle(connectionInfo.getMinimumIdle());
        config.setMaximumPoolSize(connectionInfo.getMaxPoolSize());

        if (nativeDataSource != null) {
            config.setDataSource(nativeDataSource);
        }

        // config.setLeakDetectionThreshold(30000);
        properties.forEach(config::addDataSourceProperty);

        dataSource = new HikariDataSource(config);
    }

    @Override
    public Connection openConnection() throws SQLException {
        Connection connection = dataSource.getConnection();
        if (connection == null) {
            String msg = "Driver returned null connection, make sure the connection URL "
                    + jdbcUrl
                    + " is valid for the driver "
                    + driver;
            throw new IllegalStateException(msg);
        }
        return connection;
    }

    @Override
    public void close() throws SQLException {
        LOG.warn("close datasource: {}", jdbcUrl);
        dataSource.close();
    }

    public DataSource getDataSource() {
        return dataSource;
    }
}
